using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum CurveType
{
    Linear = 0,
    InSine = 1,
    OutSine = 2,
    InOutSine = 3,
    Accelerate = 4,
    Decelerate = 5,
    InQuart = 6,
    OutQuart = 7
}

public static class Curve
{
    public delegate float Ease(float t);

    static public Ease[] eases =
    {
        t => t,
        t => Mathf.Sin(0.5f * Mathf.PI * (t - 1)) + 1f,
        t => Mathf.Sin(0.5f * Mathf.PI * t),
        t => 0.5f * Mathf.Sin(Mathf.PI * (t - 0.5f)) + 0.5f,
        t => t * t,
        t => 1 - (t - 1) * (t - 1),
        t => Mathf.Pow(t, 4),
        t => 1 - Mathf.Pow(t - 1, 4)
    };
}

public static class MalTween
{
    public static IEnumerator SetColor(SpriteRenderer sr, Color target, int duration = 0, CurveType curve = CurveType.Linear)
    {
        if (duration == 0)
        {
            sr.color = target;
        }
        else
        {
            Color origin = sr.color;
            int frame = -1;
            while (frame++ < duration)
            {
                sr.color = Color.Lerp(origin, target, Curve.eases[(int)curve](1f * frame / duration));
                yield return new WaitForFixedUpdate();
            }
        }
        yield return null;
    }

    public static IEnumerator SetRotation(Transform transform, Quaternion target, int duration = 0, CurveType curve = CurveType.Linear)
    {
        if (duration == 0)
        {
            transform.localRotation = target;
        }
        else
        {
            Quaternion origin = transform.localRotation;
            int frame = -1;
            while (frame++ < duration)
            {
                transform.localRotation = Quaternion.Lerp(origin, target, Curve.eases[(int)curve](1f * frame / duration));
                yield return new WaitForFixedUpdate();
            }
        }
        yield return null;
    }

    public static IEnumerator SetPosition(Transform transform, Vector3 target, int duration = 0, CurveType curve = CurveType.Linear)
    {
        if (duration == 0)
        {
            transform.position = target;
        }
        else
        {
            Vector3 origin = transform.position;
            int frame = -1;
            while (frame++ < duration)
            {
                transform.position = Vector3.Lerp(origin, target, Curve.eases[(int)curve](1f * frame / duration));
                yield return new WaitForFixedUpdate();
            }
        }
        yield return null;
    }

    public static IEnumerator SetScale(Transform transform, Vector3 target, int duration = 0, CurveType curve = CurveType.Linear)
    {
        if (duration == 0)
        {
            transform.localScale = target;
        }
        else
        {
            Vector3 origin = transform.localScale;
            int frame = -1;
            while (frame++ < duration)
            {
                transform.localScale = Vector3.Lerp(origin, target, Curve.eases[(int)curve](1f * frame / duration));
                yield return new WaitForFixedUpdate();
            }
        }
        yield return null;
    }
}
